package com.apps.java.javanote02;

import java.util.*;

public class _22集合_List {
    /**
     * List集合
     * 	一、概述和特点
     * 		概述：
     * 			1.有序集合（也称为序列），用户可以精准控制列表中每个元素的插入位置，用户可以通过整数索引访问元素，并搜索列表中的元素
     * 			2.与Set集合不同，列表通常允许重复的值
     * 		特点：
     * 			1.有序：存储和取出的元素顺序一致
     * 			2.可重复：可以存储重复的元素
     *
     * 	二、List集合的特有方法：
     * 		方法名						说明
     * 		void add(int index)			在此集合中的指定位置插入指定的元素
     * 		E remove(int index)			删除指定索引处的元素，返回被删除的元素
     * 		E set(int index, E element)	修改指定索引处的元素，返回被修改的元素
     * 		E get(int index)			返回指定索引处的元素
     *
     *
     * 	三、并发修改异常
     * 		ConcurrentModificationException
     * 		产生原因：
     * 			迭代器遍历的过程中。通过集合对象修改了集合中元素的长度，造成了迭代器获取元素中判断预期修改值和实际修改值不一致
     * 		解决方案：
     * 			使用for循环遍历，然后用集合对象做对应的操作即可
     *
     * 	四、ListIterator列表迭代器
     * 		概述：
     * 			通过List集合的listIterator()方法得到，所以说它是List集合特有的迭代器
     *		作用：
     *			用于允许程序员沿任意方向遍历列表的列表迭代器，在迭代期间修改列表，并获取列表中迭代器的当前位置。
     * 		常用方法：
     * 			E next()：				返回迭代中的下一个元素
     * 			boolean	hasNext()：		如果迭代具有更多元素，则返回true
     * 			E previous()：			返回列表中的上一个元素
     * 			boolean hasPrevious()：	如果此列表迭代器在相反方向遍历列表时具有更多元素。则返回true
     * 			void add(E e)：				将指定的元素插入列表
     *
     * 	五、增强for循环(for..in)
     * 		概述：
     * 			增强for循环：简化数组和Collection集合的遍历
     *			1.实现Iterator接口的类允许其对象成为增强型for语句的目标
     *			2.它是JDK5之后出现的，其内部原理是一个Iterator迭代器
     *
     * 		格式：
     * 			for(元素数据类型 变量名:数组或者Collection集合){
     * 				//此处使用变量即可，该变量就是元素
     * 			}
     *
     * 	六、数据结构
     * 		概述：数据结构是计算机存储、组织数据的方式。是指相互之间存在一种或多种特定关系的数据元素的集合
     * 		为什么使用：通常情况下，精心选择的数据结构可以带来更高的运行或存储效率
     *
     * 		常见的数据结构：
     * 			1.栈：是一种先进后出的模型[一端开口为栈顶，一端闭合为栈底]
     * 				（1）数据进入栈模型的过程称为：压/进栈
     * 				（2）数据离开栈模型的过程称为：弹/出栈
     *
     * 			2.队列：是一种先进先出的模型[一端开口为后端，另一端开头为前端]
     * 				（1）数据从后端进入队列模型的过程称为：入队列
     * 				（2）数据从前端离开队列模型的过程称为：出队列
     *
     * 			3.数组：是一种查询快、增删慢的模型
     * 				（1）查询数据通过索引定位，查询任意数据耗时相同，查询效率高
     * 				（2）删除数据时，要将原始数据删除，同时后面每个数据前移，删除效率低
     * 				（3）添加数据时，添加位置后的每个数据后移，再添加元素，添加效率极低
     *
     * 			4.链表数组：是一种查询慢、增删快的模型（与数组比较）
     *
     * 	七、List集合子类特点
     * 		List集合常用子类：
     * 			1.ArrayList：	底层数据结构是数组，查询快，增删慢
     * 			2.LinkedList：	底层数据结构是链表，查询慢，增删快
     *
     * 	八、LinkedList集合的特有功能
     * 		方法名
     * 		public void addFirst(E e):		在该列表开头插入指定的元素
     * 		public void addLast(E e):		将指定的元素追加到此列表的末尾
     * 		public E getFirst():			返回此列表中的第一个元素
     * 		public E getLast():				返回此列表中的最后一个元素
     * 		public E removeFirst():			从此列表中删除并返回第一个元素
     * 		public E removeLast():			从此列表中删除并返回最后一个元素
     *
     *
     *
     *
     */

    public static void main(String[] args) {
        //创建Lits集合对象
        List<String> list = new ArrayList<String>();


        //添加元素
        list.add("张三");
        list.add("李四");
        list.add("王五");

        //添加重复元素
        list.add("王五");

        //输出集合：可重复且有序
        System.out.println("list集合中的元素：" + list);

        //遍历list集合
        //创建迭代器对象
        Iterator<String> it = list.iterator();

        System.out.print("循环输出的值是：");

        //while循环
        while(it.hasNext()){
            String s = it.next();
            System.out.print(s);
        }
        System.out.println();

        //void add(int index)在此集合中的指定位置插入指定的元素
        list.add(0, "赵六");//不可插入到长度+1的位置，会报错
        System.out.println("指定位置插入的指定元素：" + list);

        //E remove(int index):删除指定索引处的元素，返回被删除的元素
        list.remove(3);//删除不存在的索引元素，会报错
        System.out.println("删除后的list集合：" + list);

        //E set(int index, E element)：修改指定索引处的元素，返回被修改的元素
        list.set(0, "张三");//如果是修改不存在的索引，会报错
        System.out.println("修改后的list集合：" + list);

        //E get(int index)返回指定索引处的元素
        System.out.println("获取指定索引的元素：" + list.get(3));//返回不存在的索引，会报错

        for(int i=0 ; i<list.size() ; i++){
            System.out.println("索引" + i + "的元素：" + list.get(i));
        }

        //ListIterator
        //创建ListIterator对象
        ListIterator<String> it3 = list.listIterator();

        //使用迭代器遍历集合
        while(it3.hasNext()){
            String s = it3.next();
            if(s.equals("王五")){
                //void add(E e)：将指定的元素插入列表
                it3.add("小白");
            }
        }

        System.out.println("使用迭代器添加元素：" + list);

        System.out.print("反方向遍历集合：");
        //使用list迭代器反方向遍历list集合
        while(it3.hasPrevious()){
            String s = it3.previous();
            System.out.print(s);
        }

        System.out.println();

        //增强For循环
        System.out.print("使用for..in遍历的集合:");
        for(String s : list){
            System.out.print(s);
        }

        //并发修改异常
		/*
		while(it.hasNext()){
			String s = it.next();
			if(s.equals("张三")){
				list.add("小白");
				System.out.println("aaa");
			}
		}
		*/

		/*
		//使用for循环或者list迭代器可以解决并发修改异常的问题
		for(int i=0 ; i<list.size() ; i++){
			String s = list.get(i);
			if(s.equals("王五")){
				list.add("小白");
			}
		}
		System.out.println(list);
		*/

        //LinkedList集合特有功能
        LinkedList<String> linked = new LinkedList<String>();

        linked.add("砂浆");
        linked.add("萨克");
        linked.add("爱妃");

        //1. public void addFirst(E e):在该列表开头插入指定的元素
        linked.addFirst("小奥比");
        System.out.println("\n在列表开头插入元素：" + linked);

        //2. public void addLast(E e):将指定的元素追加到此列表的末尾
        linked.addLast("阿克苏");
        System.out.println("在列表末尾插入元素：" + linked);

        //3. public E getFirst():返回此列表中的第一个元素
        System.out.println("第一个元素是：" + linked.getFirst());

        //4. public E getLast():返回此列表中的最后一个元素
        System.out.println("最后一个元素是：" + linked.getLast());

        //5. public E removeFirst():从此列表中删除并返回第一个元素
        System.out.println("删除第一个元素：" + linked.removeFirst());
        System.out.println("删除后：" + linked);

        //6. public E removeLast():从此列表中删除并返回最后一个元素
        System.out.println("删除最后一个元素：" + linked.removeLast());
        System.out.println("删除后：" + linked);


    }
}
